﻿using MD5Hash;
using MediatR;
using SmartCity.BasicData.Api.Application.Command.Accont;
using SmartCity.BasicData.Api.DTOs;
using SmartCity.BasicData.Domain.Entities;
using SmartCity.BasicData.ErrorCoce;
using SmartCity.BasicData.Infrastructure.Extention;
using SmartCity.BasicData.Infrastructure.Interface;
using Yitter.IdGenerator;

namespace SmartCity.BasicData.Api.Application.Handler.Accont
{
    /// <summary>
    /// 中介者 - 登录处理类
    /// </summary>
    public class LoginAccountHandler : IRequestHandler<LoginAccountCommand, ApiResult<LoginDTO>>

    {
        private readonly ILogger<LoginAccountHandler> logger;
        private readonly IBaseRepository<AccountModel> accountRepo;
        private readonly IBaseRepository<RoleModel> roleRepo;
        private readonly IBaseRepository<AccountRoleModel> accountRoleRepo;
        private readonly IBaseRepository<LogModel> logRepo;

        /// <summary>
        /// 通过构造函数注入登陆所需的资源
        /// </summary>
        /// <param name="logger"></param>
        /// <param name="accountRepo"></param>
        /// <param name="roleRepo"></param>
        /// <param name="accountRoleRepo"></param>
        /// <param name="logRepo"></param>
        public LoginAccountHandler(ILogger<LoginAccountHandler> logger, IBaseRepository<AccountModel> accountRepo, IBaseRepository<RoleModel> roleRepo, IBaseRepository<AccountRoleModel> accountRoleRepo, IBaseRepository<LogModel> logRepo)
        {
            this.logger = logger;
            this.accountRepo = accountRepo;
            this.roleRepo = roleRepo;
            this.accountRoleRepo = accountRoleRepo;
            this.logRepo = logRepo;
        }

        /// <summary>
        /// 中介者- 登录处理方法
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task<ApiResult<LoginDTO>> Handle(LoginAccountCommand request, CancellationToken cancellationToken)
        {
            logger.LogInformation($"{request.AccountName}正尝试登录.");
            await logRepo.CreateAsync(new LogModel()
            {
                Id = YitIdHelper.NextId(),
                LogContent = $"{request.AccountName}正尝试登录.",
                CreateTime = DateTime.Now,
                Creator = request.AccountName

            });

            //查找要登录的账号
            var acc = accountRepo.GetAll().Where(x => x.AccountName == request.AccountName).FirstOrDefault();
            if (acc == null)
            {
                await logRepo.CreateAsync(new LogModel()
                {
                    Id = YitIdHelper.NextId(),
                    LogContent = $"不存账号:{request.AccountName}.",
                    CreateTime = DateTime.Now,
                    Creator = request.AccountName

                });
                logger.LogInformation($"不存账号:{request.AccountName}.");
                return new ApiResult<LoginDTO>().Fail("账号不存在!");
            }

            var pwd = request.Password.GetMD5();
            if (acc.Password != pwd)
            {
                logger.LogInformation($"{request.AccountName}密码错误.");


                await logRepo.CreateAsync(new LogModel()
                {
                    Id = YitIdHelper.NextId(),
                    LogContent = $"{request.AccountName}密码错误.",
                    CreateTime = DateTime.Now,
                    Creator = request.AccountName

                });
                return new ApiResult<LoginDTO>().Fail("密码错误!");
            }
            //查找登录用户的账号角色关系实体
            var accRole = accountRoleRepo.GetAll().Where(x => x.AccountId == acc.Id).FirstOrDefault();
            if (accRole == null)
            {
                logger.LogInformation($"{request.AccountName}无角色.");
                return new ApiResult<LoginDTO>().Error("请联系管理员为您分配角色!");
            }

            //查找登录用户的角色信息
            var role = await roleRepo.GetModel(accRole.RoleId);
            if (role == null)
            {
                logger.LogInformation($"系统未配置角色.");
                return new ApiResult<LoginDTO>().Error("请联系管理员配置角色!");
            }

            LoginDTO loginDTO = new LoginDTO()
            {
                AccountName = acc.AccountName,
                RealName = acc.RealName,
                RoleName = role.RoleName,
                JwtToken = JwtExtention.CreateTokenString(acc.AccountName, acc.RealName, role.RoleName)
            };

            await logRepo.CreateAsync(new LogModel()
            {
                Id = YitIdHelper.NextId(),
                LogContent = $"{request.AccountName},登录成功.",
                CreateTime = DateTime.Now,
                Creator = request.AccountName

            });
            logger.LogInformation($"{request.AccountName},登录成功.");
            return new ApiResult<LoginDTO>().Success("恭喜您,登录成功!", loginDTO);
        }
    }
}
